package edu.gdpu.gc;

/**
 * @author mazebin
 * @date 2021年 07月15日 23:27:46
 * 此代码演示两点
 * 1.对象可以在GC时自我拯救
 * 2.这种自救机会只有一次，因为一个对象的finalize方法只会最多被系统调用一次
 */
public class FinalizeEscapeGC {
    private static FinalizeEscapeGC SAVE_HOOK = null;
    public void isActive(){
        System.out.println("yes,i am active");
    }
//垃圾回收器在释放内存的时候，会先调用finalize()
    //(1) 对象不一定会被回收
    //（2）垃圾回收不是析构函数
    //（3）垃圾回收只与内存有关
    //（4）垃圾回收和finalize方法都是靠不住的，只要JVM还没有快到耗尽内存的地步，
// 是可以进行垃圾回收的
    @Override//这个方法不推荐使用,重写了这个方法，会将这个对象注册到FinalizerThread的ReferenceQueue中，垃圾回收时将不会回收ReferenceQueue的对象
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("finalize method executed");
        FinalizeEscapeGC .SAVE_HOOK =this;
    }

    public static void main(String[] args) throws Exception {
        SAVE_HOOK = new FinalizeEscapeGC();
        //对象第一次成功拯救自己
        SAVE_HOOK = null;
        //显示调用gc(Full GC)
        System.gc();
        //因为finalize()方法优先级较低，所以暂停0.5m
        Thread.sleep(500);
        if(SAVE_HOOK != null ){
            SAVE_HOOK.isActive();

        }
        else{
            System.out.println("no i am dead");
        }
        System.out.println(SAVE_HOOK .equals(null));
//        //和上面的代码一样，但是这次自我拯救失败
//        SAVE_HOOK = null;
//        System.gc();
//
//        //因为finalize()方法优先级很低，所以暂停0.5m
//        Thread.sleep(500);
//        if (SAVE_HOOK != null) {
//            SAVE_HOOK.isActive();
//        } else {
//            System.out.println("no, i am dead ");
//        }

    }
}
